package erfgame.core.world.terrain.factory;

import java.awt.Point;
import java.util.Arrays;


import erfgame.core.world.World;
import erfgame.core.world.WorldContext;
import erfgame.core.world.terrain.MaterialType;
import erfgame.core.world.terrain.TerrainUpdate;
import erfgame.core.world.terrain.TerrainUpdateByMaterialTypeFactory;
import erfgame.core.world.terrain.TerrainUpdateGroup;

public class GridBlockTerrainUpdateByMaterialTypeFactory implements
		TerrainUpdateByMaterialTypeFactory {
	
	private WorldContext worldContext;
	
	private short flags;
	private int gridDiagaonalAdjust;
	private int depthAdjust;
	private int depthMult;
	
	public GridBlockTerrainUpdateByMaterialTypeFactory( WorldContext worldContext, short flags ) {
		this.worldContext = worldContext;
		this.flags = flags;
	}
	
	public void setGridDiagonalAdjust( int gridDiagonalAdjust ) {
		this.gridDiagaonalAdjust = gridDiagonalAdjust;
	}
	
	public void setDepthAdjust( int depthAdjust ) {
		this.depthAdjust = depthAdjust;
	}
	
	public void setDepthMult( int depthMult ) {
		this.depthMult = depthMult;
	}

	public TerrainUpdateGroup createTerrainUpdate(byte materialTypeId) {
		World world = worldContext.getCurrentWorld();
		int diagonal = world.getGridDiagonal() + gridDiagaonalAdjust;
		int width = diagonal;
		int height = diagonal;
		int depth = world.getBlockDepth() * depthMult + depthAdjust;
		
		int widthOn2 = width/2;
		int heightOn2 = height/2;
		int diagonalOn2 = diagonal/2;
		// TODO reuse memory
		short[][][] terrain = new short[width][height][depth];
		Point p = new Point();
		for( int x=width; x>0; ) {
			x--;
//			int dx = Math.abs( widthOn2 - x );
			for( int y=height; y>0; ) {
				y--;
				p = world.getGridCoordinates(x+diagonalOn2, y, p);
				if( p.x == 1 && p.y == 1 ) {
//				int dy = Math.abs( heightOn2 - y );
//				if( dx + dy <= diagonalOn2 ) {
					Arrays.fill( terrain[x][y], (short)(materialTypeId | flags) );
//				}
				}
			}
		}
		return new TerrainUpdateGroup( new TerrainUpdate( terrain, width, height, depth+1 ) );
	}
}
